﻿#include "concurrentAlloc.h"

// 申请内存
void* ConcurrentAlloc(size_t size)
{
	if (size > MAX_BYTES)
	{
		size_t alignSize = SizeClass::RoundUp(size);
		size_t kpage = alignSize >> PAGE_SHIFT;

		PageCache::getInstance()->lock();
		Span* span = PageCache::getInstance()->newSpan(kpage);
		span->m_objSize = size;
		PageCache::getInstance()->unlock();

		void* ptr = (void*)(span->m_pageId << PAGE_SHIFT);
		return ptr;
	}
	else
	{
		// 通过TLS 每个线程无锁的获取自己的专属的ThreadCache对象
		if (pTLSThreadCache == nullptr)
		{
			static ObjectPool<ThreadCache> tcPool;
			//pTLSThreadCache = new ThreadCache;
			pTLSThreadCache = tcPool.New();
		}

		//cout << std::this_thread::get_id() << ":" << pTLSThreadCache << endl;

		return pTLSThreadCache->allocate(size);
	}	
}

// 释放内存
void ConcurrentFree(void* ptr)
{
	Span* span = PageCache::getInstance()->mapObjectToSpan(ptr);
	size_t size = span->m_objSize;

	if (size > MAX_BYTES)
	{
		PageCache::getInstance()->lock();
		PageCache::getInstance()->releaseSpanToPageCache(span);
		PageCache::getInstance()->unlock();
	}
	else
	{
		assert(pTLSThreadCache);
		pTLSThreadCache->deallocate(ptr, size);
	} 
}